--#region 变量与作用域 local x = 10-- local:局部变量(推荐默认都用 local) y = 20-- 无 local:全局变量(容易污染命名空间,不推荐) do local x = 99-- 块级作用域:do ... end 内部的 x 与外部不同 print("inner x", x) -- 99 end print("outer x", x) -- 10 --#endregion
--#region 数字与字符串 local a, b = 7, 3 print(a / b) -- 浮点除法 2.333... print(a // b) -- 整除 2 print(a % b) -- 取模 1 print(2 ^ 3) -- 次方 8
local s = "Lua" print("hi " .. s) -- 字符串拼接用 .. print(#s) -- 字符串长度(对表是“长度运算符”,见后文) --#endregion
--#region 多重赋值与交换 local i, j = 1, 2 i, j = j, i -- 交换变量 print(i, j) -- 2 1 --#endregion
--#region 函数基础 localfunctionadd(x, y)-- 定义函数(local 防止泄露到全局) return x + y -- Lua 支持多返回值:return a, b, c end print(add(3, 4)) -- 7 --#endregion
--#region 闭包(捕获外部变量) localfunctionmakeCounter()-- 工厂函数 local n = 0-- 被捕获的“上值”(upvalue) returnfunction()-- 返回匿名函数 n = n + 1 return n end end local nextId = makeCounter() print(nextId(), nextId()) -- 1 2(状态被函数记住) --#endregion
--#region 可变参数 ... localfunctionsum(...)-- ... 接收任意数量实参 local total = 0 for _, v inipairs({...}) do-- 把 ... 收集到新表再遍历(简单直观) total = total + v end return total end print(sum(1,2,3,4)) -- 10 --#endregion
--#region 冒号语法糖(面向对象风格) local Player = {} functionPlayer.say(self, msg)-- 点语法:需要手动传 self print(self.name .. ": " .. msg) end functionPlayer:say2(msg)-- 冒号语法:定义时自动加 self 参数 print(self.name .. ": " .. msg) end local p = {name = "Lee"} Player.say(p, "hello") -- 等价 p: say2("hi") -- 等价于 Player.say2(p, "hi") --#endregion
3. 表(Table)最重要:从入门到专家
3.1 构造、读写与删除
1 2 3 4 5 6 7 8 9 10 11 12 13
--#region 构造器(数组式 + 字典式可混用) local arr = {10, 20, 30} -- “数组式”下标从 1 开始 local dict = {x = 1, y = 2} -- “字典式”键是字符串 local mix = {100, a = 5, ["weird-key"] = 7, [true] = "ok"} -- 任意键 --#endregion
--#region 遍历 for i, v inipairs(arr) do-- ipairs:连续整数键 1..n,遇到第一个 nil 停 print(i, v) end for k, v inpairs(mix) do-- pairs:遍历所有键(无序,不保证顺序稳定) print(k, v) end --#endregion
--#region 引用语义 local t1 = {a=1} local t2 = t1 -- 赋值只是“指向同一张表” t2.a = 9 print(t1.a) -- 9 --#endregion
--#region 浅拷贝 localfunctionshallow_copy(src) local dst = {} for k, v inpairs(src) do dst[k] = v -- 仅复制第一层,嵌套表仍是“同一个引用” end return dst end --#endregion
--#region 深拷贝(带环检测) localfunctiondeep_copy(src, seen) iftype(src) ~= "table"thenreturn src end if seen and seen[src] thenreturn seen[src] end local dst = {} seen = seen or {} seen[src] = dst for k, v inpairs(src) do dst[deep_copy(k, seen)] = deep_copy(v, seen) end -- 可选:拷贝元表 returnsetmetatable(dst, getmetatable(src)) end --#endregion
--#region 运算符重载与属性“魔法” local vec = {x=1, y=2} local mt = {} mt.__add = function(a,b)return {x=a.x+b.x, y=a.y+b.y} end-- 重载 + mt.__tostring = function(v)return ("(%d,%d)"):format(v.x,v.y) end mt.__index = function(t,k) if k == "len"then returnmath.sqrt(t.x*t.x + t.y*t.y) -- 惰性“属性” end end setmetatable(vec, mt) print(vec + {x=3,y=4}) -- (4,6) print(vec.len) -- 2.236... --#endregion
--#region “类风格”构造与方法 local Class = {} -- 类表(方法定义在它上面) Class.__index = Class -- 实例查不到键时从 Class 上找(方法) functionClass:new(name)-- 构造器 local o = {name = name} -- 实例 returnsetmetatable(o, Class) -- 绑定元表 end functionClass:say(msg)-- 方法 print(self.name .. ": " .. msg) end local c = Class:new("Alice") c:say("yo") -- Alice: yo --#endregion
--#region 模式匹配(不完全等于正则,但够用) local text = "id=42 user=lee" for k, v instring.gmatch(text, "(%w+)=(%w+)") do print(k, v) -- id 42 / user lee end --#endregion
5. 协程:可暂停的函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
--#region 生产者-消费者示例 localfunctionproducer() returncoroutine.create(function() for i=1,3do coroutine.yield(i) -- 产出一个值并挂起 end return"done"-- 最终返回 end) end